今天介紹 watchEffect 與 Lifecycle hooks
const count = ref(0)
watchEffect(() => console.log(count.value))  // log 出 0
setTimeout(() => {
  count.value++  // log 出 1, 2, 3...
}, 100)
watchEffect 回傳一個函數 WachStopHandle,該函數無回傳值,主要是用來讓我們停止 watchEffect。
參考一下這個範例:
// 建立一個 watchEffect
const watcher  = watchEffect(() => '')
watcher() // 停止 watchEffect
此外, WatchStopHandle 接受一個參數 onInvalidate,這是一個 function。在某些場合我們的 watcher 會使用到異步操作,這些操作可能需要在執行後做一些其他任務,例如更改狀態,這時就可以使用到這個 onInvalidate function,它的觸發時機有兩個實行時機:
範例:
// 這個 watcher 會在 token 變更的時候被觸發
const watcher = watchEffect(async (onInvalidate) => {
    state.user = async apis.getUser(token.value)
    
    // 當 token 變更後,會執行 token.forget 將之前的 token 清除
    onInvalidate(() => {
        token.forget()
    })
})
watchEffect 的實行時機是在 Vue 元件的狀態更新後執行。
<template>
  <div>{{ count }}</div>
</template>
<script>
  export default {
    setup() {
      const count = ref(0)
      watchEffect(() => {
        console.log(count.value)
      })
      return {
        count,
      }
    },
  }
</script>
如果你有要同步甚至在狀態更新前執行 effect 的需求,可以透過傳遞第二個參數給 watchEffect 來控制,watchEffect 的第二個參數是一個選擇性物件,這個物件有一個屬性 flush,用來控制執行時機,預設值是 post,你可以將它改成 sync 來變成同步,或是 pre 來達成狀態更新前先執行 effect。
export default {
  setup() {
    watchEffect(() => {
      // something here ..
    }, { flush: 'sync' })  // 將 effect 改為同步執行
  }
}
這裡是所有的 Lifecycle hooks,可透過 import 拿到。
在 Vue3 中並沒有 beforeCreate 與 created,如果你有想寫在這兩個 hook 裡的東西,請直接寫在 setup 裡面。
setup 會在 mount 之前執行,所以如果你有需要訪問到 DOM,請將程式寫在 onMounted 中。
export default {
  setup() {
    onMounted(() => {
        // do something with DOM ...
    })
  }
}